<template>
  <div id="xterm-container"></div>
</template>

<script>
import './xterm.css'
import {Terminal} from '@/utils/xterm'
import {getToken} from '@/utils/auth'

let terminal
let socket

const wsPath =
  process.env.NODE_ENV === 'development' ? 'ws://10.17.12.216:9301/ws/mgr' : `ws://${window.location.host}/ws/mgr`
const promptSymbol = '\x1B[1;3;32m[ws@ssh]\x1B[1;3;31m$ \x1B[0m'

const MESSAGE_TYPE = {
  GATE_DEBUG: 'GATE_DEBUG'
}

export default {
  name: 'Terminal',

  data() {
    return {
      gwId: ''
    }
  },

  mounted() {
    this.gwId = this.$route.query.gwId
    terminal = new Terminal()

    terminal.open(document.getElementById('xterm-container'))

    terminal.write(promptSymbol)
    let inputBuffer = '' // 存储输入的字符

    // 监听输入
    terminal.onData((data) => {
      console.log(data)
      console.log('\\x' + data.charCodeAt().toString(16))

      // Enter
      if (data === '\r') {
        if (inputBuffer.length === 0) {
          inputBuffer += '\x0d'
        }
        this.sendMessage(MESSAGE_TYPE.GATE_DEBUG, inputBuffer)
        inputBuffer = '' // 清空输入缓冲区
        this.writeln('') // 换行
      } else if (data === '\x7f') {
        // 检查是否按下了退格键
        // '\x7f' 是退格键的 ASCII 码
        if (inputBuffer.length > 0) {
          inputBuffer = inputBuffer.slice(0, -1) // 删除最后一个字符
          terminal.write('\b \b') // 在终端中显示退格效果
        }
      } else if (['\x1b[A', '\x1b[B', '\x1b[C', '\x1b[D'].includes(data)) {
        // 方向键
      } else if (data === '\x03') {
        // Ctrl + C
        this.sendMessage(MESSAGE_TYPE.GATE_DEBUG, data)
        inputBuffer = '' // 清空输入缓冲区
        this.writeln('^C') // 换行
      } else {
        // 处理普通输入
        inputBuffer += data // 将输入字符添加到缓冲区
        terminal.write(data) // 显示输入字符
      }
    })

    this.adjustTerminalSize()
    this.initSocket()

    window.addEventListener('resize', () => {
      this.adjustTerminalSize()
    })
  },

  methods: {
    adjustTerminalSize() {
      const terminalElement = document.getElementById('xterm-container')
      const terminalHeight = terminalElement.clientHeight
      const rowHeight = terminal._core._renderService.dimensions.css.cell.height // 每行高度
      const availableRows = Math.floor(terminalHeight / rowHeight) // 可显示的行数
      const cols = terminal.cols // 使用当前列数

      terminal.resize(cols, availableRows) // 调整终端大小
    },

    sendMessage(type, data) {
      socket.send(JSON.stringify({type, data, clientId: getToken(), gwId: this.gwId}))
    },

    // 输入
    writeln(data) {
      terminal.writeln(data)
      terminal.write(promptSymbol)
    },

    // 输出
    writeMessage(data) {
      terminal.write('\b'.repeat(promptSymbol.length) + ' '.repeat(promptSymbol.length) + '\b'.repeat(promptSymbol.length))
      this.writeln(data)
    },

    initSocket() {
      const subProtocols = getToken() + '-' + this.gwId
      socket = new WebSocket(wsPath, subProtocols)

      socket.onopen = (event) => {
        this.writeMessage('server Connected.')
      }
      socket.onmessage = (event) => {
        console.log('socket onmessage:', event.data)

        // 清空标识符
        terminal.write('\b'.repeat(promptSymbol.length) + ' '.repeat(promptSymbol.length) + '\b'.repeat(promptSymbol.length))

        this.writeMessage(event.data)
      }

      socket.onclose = (event) => {
        this.writeMessage('connection Closed.')
      }

      socket.onerror = (event) => {
        this.writeMessage(`connect Error: ${wsPath}`)
      }
    }
  }
}
</script>

<style scoped>
#xterm-container {
  height: 100vh;
}
</style>
